﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace WindowsGame1
{
    class TileMap
    {
        List<TileMapLayer> mapLayers = new List<TileMapLayer>();
        CollisionLayer collisionLayer;
        int mapWidth;
        int mapHeight;

        public TileMap(int width, int height, List<TileMapLayer> layers)
        {
            this.mapWidth = width;
            this.mapHeight = height;
            this.mapLayers = layers;
            collisionLayer = new CollisionLayer(mapWidth, mapHeight);
            foreach (TileMapLayer mapLayer in mapLayers)
            {
                ProcessCollisionLayer(mapLayer);
            }
        }

        public int MapWidth
        {
            get { return mapWidth; }
        }

        public int MapHeight
        {
            get { return mapHeight; }
        }

        private void ProcessCollisionLayer(TileMapLayer layer)
        {
            for (int y = 0; y < mapHeight; y++)
                for (int x = 0; x < mapWidth; x++)
                {
                    switch (layer.GetTile(x, y))
                    {
                        case 4:
                            collisionLayer.SetTile(x, y, CollisionType.Unpassable);
                            break;
                    }
                }
        }

        public CollisionType GetCollisionValue(int x, int y)
        {
            return collisionLayer.GetTile(x, y);
        }

        public bool CheckUpAndLeft(Rectangle nextRectangle)
        {
            Point tile1 = TileEngine.VectorToCell(
            new Vector2(nextRectangle.X, nextRectangle.Y));
            Point tile2 = TileEngine.VectorToCell(
            new Vector2(nextRectangle.X + nextRectangle.Width,
            nextRectangle.Y + nextRectangle.Height));
            bool doesCollide = false;
            if (tile1.X < 0 || tile1.Y < 0)
                return !doesCollide;
            for (int y = tile1.Y; y <= tile2.Y; y++)
                for (int x = tile1.X; x <= tile2.X; x++)
                    if (GetCollisionValue(x, y) == CollisionType.Unpassable)
                        doesCollide = true;
            return doesCollide;
        }

        public bool CheckUp(Rectangle nextRectangle)
        {
            Point tile1 = TileEngine.VectorToCell(
            new Vector2(nextRectangle.X, nextRectangle.Y));
            Point tile2 = TileEngine.VectorToCell(
            new Vector2(nextRectangle.X + nextRectangle.Width - 1,
            nextRectangle.Y + nextRectangle.Height));
            bool doesCollide = false;
            if (tile1.Y < 0)
                return !doesCollide;
            int y = tile1.Y;
            for (int x = tile1.X; x <= tile2.X; x++)
                if (GetCollisionValue(x, y) == CollisionType.Unpassable)
                    doesCollide = true;
            return doesCollide;
        }

        public bool CheckUpAndRight(Rectangle nextRectangle)
        {
            Point tile1 = TileEngine.VectorToCell(
            new Vector2(nextRectangle.X, nextRectangle.Y));
            Point tile2 = TileEngine.VectorToCell(
            new Vector2(nextRectangle.X + nextRectangle.Width + 1,
            nextRectangle.Y + nextRectangle.Height));
            bool doesCollide = false;
            if (tile2.X >= mapWidth || tile1.Y < 0)
                return !doesCollide;
            for (int y = tile1.Y; y <= tile2.Y; y++)
                for (int x = tile1.X; x <= tile2.X; x++)
                    if (GetCollisionValue(x, y) == CollisionType.Unpassable)
                        doesCollide = true;
            return doesCollide;
        }

        public bool CheckLeft(Rectangle nextRectangle)
        {
            Point tile1 = TileEngine.VectorToCell(
            new Vector2(nextRectangle.X, nextRectangle.Y));
            Point tile2 = TileEngine.VectorToCell(
            new Vector2(nextRectangle.X + nextRectangle.Width,
            nextRectangle.Y + nextRectangle.Height - 1));
            bool doesCollide = false;
            if (tile1.X < 0)
                return !doesCollide;
            int x = tile1.X;
            for (int y = tile1.Y; y <= tile2.Y; y++)
            {
                if (GetCollisionValue(x, y) == CollisionType.Unpassable)
                    doesCollide = true;
            }
            return doesCollide;
        }

        public bool CheckRight(Rectangle nextRectangle)
        {
            Point tile1 = TileEngine.VectorToCell(
            new Vector2(nextRectangle.X, nextRectangle.Y));
            Point tile2 = TileEngine.VectorToCell(
            new Vector2(nextRectangle.X + nextRectangle.Width,
            nextRectangle.Y + nextRectangle.Height - 1));
            bool doesCollide = false;
            if (tile2.X >= mapWidth)
                return !doesCollide;
            int x = tile2.X;
            for (int y = tile1.Y; y <= tile2.Y; y++)
            {
                if (GetCollisionValue(x, y) == CollisionType.Unpassable)
                    doesCollide = true;
            }
            return doesCollide;
        }

        public bool CheckDownAndLeft(Rectangle nextRectangle)
        {
            Point tile1 = TileEngine.VectorToCell(
            new Vector2(nextRectangle.X, nextRectangle.Y));
            Point tile2 = TileEngine.VectorToCell(
            new Vector2(nextRectangle.X + nextRectangle.Width,
            nextRectangle.Y + nextRectangle.Height));
            bool doesCollide = false;
            if (tile1.X < 0 || tile2.Y >= mapHeight)
                return !doesCollide;
            for (int y = tile1.Y; y <= tile2.Y; y++)
                for (int x = tile1.X; x <= tile2.X; x++)
                    if (GetCollisionValue(x, y) == CollisionType.Unpassable)
                        doesCollide = true;
            return doesCollide;
        }

        public bool CheckDown(Rectangle nextRectangle)
        {
            Point tile1 = TileEngine.VectorToCell(
            new Vector2(nextRectangle.X, nextRectangle.Y));
            Point tile2 = TileEngine.VectorToCell(
            new Vector2(nextRectangle.X + nextRectangle.Width - 1,
            nextRectangle.Y + nextRectangle.Height));
            bool doesCollide = false;
            if (tile2.Y >= mapHeight)
                return !doesCollide;
            int y = tile2.Y;
            for (int x = tile1.X; x <= tile2.X; x++)
                if (GetCollisionValue(x, y) == CollisionType.Unpassable)
                    doesCollide = true;
            return doesCollide;
        }

        public bool CheckDownAndRight(Rectangle nextRectangle)
        {
            Point tile1 = TileEngine.VectorToCell(
            new Vector2(nextRectangle.X, nextRectangle.Y));
            Point tile2 = TileEngine.VectorToCell(
            new Vector2(nextRectangle.X + nextRectangle.Width,
            nextRectangle.Y + nextRectangle.Height));
            bool doesCollide = false;
            if (tile2.X >= mapWidth || tile2.Y >= mapHeight)
                return !doesCollide;
            for (int y = tile1.Y; y <= tile2.Y; y++)
                for (int x = tile1.X; x <= tile2.X; x++)
                    if (GetCollisionValue(x, y) == CollisionType.Unpassable)
                        doesCollide = true;
            return doesCollide;
        }

        public void Draw(SpriteBatch spriteBatch,
        Texture2D texture, Tileset tileset)
        {
            foreach (TileMapLayer layer in mapLayers)
            {
                layer.Draw(spriteBatch, texture, tileset);
            }
        }
    }
}